home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 676-700 / 682 / rexxhostlib / rexxhostlib.c < prev    next >
C/C++ Source or Header  |  1995-03-18  |  14KB  |  687 lines

  1. /*
  2. **    rexxhost.library - ARexx host management support library
  3. **
  4. **    Copyright © 1990-1992 by Olaf `Olsen' Barthel
  5. **        All Rights Reserved
  6. */
  7.  
  8.     /* CreateRexxHost(HostName):
  9.      *
  10.      *    Creates a RexxHost (special MsgPort) with a given name.
  11.      *    Returns NULL if port already exists.
  12.      */
  13.  
  14. struct RexxHost * __saveds __asm
  15. CreateRexxHost(register __a0 STRPTR HostName)
  16. {
  17.     struct RexxHost *RexxHost;
  18.  
  19.         /* Valid name given? */
  20.  
  21.     if(HostName)
  22.     {
  23.         if(HostName[0])
  24.         {
  25.                 /* Already present? */
  26.  
  27.             if(!FindPort(HostName))
  28.             {
  29.                     /* Allocate the port body. */
  30.  
  31.                 if(RexxHost = (struct RexxHost *)AllocMem(sizeof(struct RexxHost),MEMF_PUBLIC | MEMF_CLEAR))
  32.                 {
  33.                         /* Allocate a signal bit. */
  34.  
  35.                     if((RexxHost -> rh_Port . mp_SigBit = AllocSignal(-1)) != -1)
  36.                     {
  37.                             /* Initialize the MsgPort node head. */
  38.  
  39.                         RexxHost -> rh_Port . mp_Node . ln_Type    = NT_MSGPORT;
  40.                         RexxHost -> rh_Port . mp_Node . ln_Pri    = 1;
  41.  
  42.                             /* Allocate memory for MsgPort name. */
  43.  
  44.                         if(RexxHost -> rh_Port . mp_Node . ln_Name = (UBYTE *)AllocMem(strlen(HostName) + 1,MEMF_PUBLIC))
  45.                         {
  46.                                 /* Copy the name. */
  47.  
  48.                             strcpy(RexxHost -> rh_Port . mp_Node . ln_Name,HostName);
  49.  
  50.                                 /* Deal with the rest of the flags. */
  51.  
  52.                             RexxHost -> rh_Port . mp_Flags        = PA_SIGNAL;
  53.                             RexxHost -> rh_Port . mp_SigTask    = SysBase -> ThisTask;
  54.  
  55.                                 /* A dummy ID. */
  56.  
  57.                             RexxHost -> rh_SpecialID = 'REXX';
  58.  
  59.                                 /* Finally add it to the public port list. */
  60.  
  61.                             AddPort(&RexxHost -> rh_Port);
  62.  
  63.                                 /* And return it to the caller. */
  64.  
  65.                             return(RexxHost);
  66.                         }
  67.  
  68.                         FreeSignal(RexxHost -> rh_Port . mp_SigBit);
  69.                     }
  70.  
  71.                     FreeMem(RexxHost,sizeof(struct RexxHost));
  72.                 }
  73.             }
  74.         }
  75.     }
  76.  
  77.     return(NULL);
  78. }
  79.  
  80.     /* DeleteRexxHost(RexxHost):
  81.      *
  82.      *    Deletes a MsgPort as created by CreateRexxHost().
  83.      *    Returns NULL, so user can do 'Host = DeleteRexxHost(Host);'.
  84.      */
  85.  
  86. VOID * __saveds __asm
  87. DeleteRexxHost(register __a0 struct RexxHost *RexxHost)
  88. {
  89.         /* Valid host port given? */
  90.  
  91.     if(RexxHost)
  92.     {
  93.         if(RexxHost -> rh_SpecialID == 'REXX')
  94.         {
  95.                 /* Remove it from the public list. */
  96.  
  97.             RemPort(&RexxHost -> rh_Port);
  98.  
  99.                 /* Free the name. */
  100.  
  101.             FreeMem(RexxHost -> rh_Port . mp_Node . ln_Name,strlen(RexxHost -> rh_Port . mp_Node . ln_Name) + 1);
  102.  
  103.                 /* Free the allocated signal bit. */
  104.  
  105.             FreeSignal(RexxHost -> rh_Port . mp_SigBit);
  106.  
  107.                 /* Free the body. */
  108.  
  109.             FreeMem(RexxHost,sizeof(struct RexxHost));
  110.         }
  111.     }
  112.  
  113.     return(NULL);
  114. }
  115.  
  116.     /* SendRexxCommand(HostPort,CommandString,FileExtension,HostName):
  117.      *
  118.      *    Sends a command to the rexx server, requires pointers
  119.      *    to the MsgPort of the calling Host and the command string.
  120.      *    File extension and host name are optional and may be
  121.      *    NULL.
  122.      */
  123.  
  124. LONG __saveds __asm
  125. SendRexxCommand(register __a0 struct RexxHost *HostPort,register __a1 STRPTR CommandString,register __a2 STRPTR FileExtension,register __a3 STRPTR HostName)
  126. {
  127.     struct MsgPort    *RexxPort = (struct MsgPort *)FindPort(RXSDIR);
  128.     struct RexxMsg    *HostMessage;
  129.  
  130.         /* Valid pointers given? */
  131.  
  132.     if(CommandString && HostPort && RexxPort)
  133.     {
  134.         if(HostPort -> rh_SpecialID == 'REXX')
  135.         {
  136.                 /* No special host name given? Take the MsgPort name. */
  137.  
  138.             if(!HostName)
  139.                 HostName = (STRPTR)HostPort -> rh_Port . mp_Node . ln_Name;
  140.  
  141.                 /* No file name extension? Take the default. */
  142.  
  143.             if(!FileExtension)
  144.                 FileExtension = (STRPTR)"rexx";
  145.  
  146.                 /* Create the message. */
  147.  
  148.             if(HostMessage = CreateRexxMsg((struct MsgPort *)HostPort,FileExtension,HostName))
  149.             {
  150.                     /* Add the command. */
  151.  
  152.                 if(HostMessage -> rm_Args[0] = CreateArgstring(CommandString,strlen(CommandString)))
  153.                 {
  154.                         /* This is a command, not a function. */
  155.  
  156.                     HostMessage -> rm_Action = RXCOMM;
  157.  
  158.                         /* Release it... */
  159.  
  160.                     PutMsg(RexxPort,HostMessage);
  161.  
  162.                         /* Successful action. */
  163.  
  164.                     return(TRUE);
  165.                 }
  166.  
  167.                 DeleteRexxMsg(HostMessage);
  168.             }
  169.         }
  170.     }
  171.  
  172.     return(FALSE);
  173. }
  174.  
  175.     /* FreeRexxCommand(RexxMessage):
  176.      *
  177.      *    Frees the contents of a RexxMsg.
  178.      */
  179.  
  180. VOID __saveds __asm
  181. FreeRexxCommand(register __a0 struct RexxMsg *RexxMessage)
  182. {
  183.         /* Valid pointer given? */
  184.  
  185.     if(RexxMessage)
  186.     {
  187.         if(RexxMessage -> rm_Node . mn_Node . ln_Type == NT_REPLYMSG)
  188.         {
  189.                 /* Remove argument. */
  190.  
  191.             if(RexxMessage -> rm_Args[0])
  192.                 DeleteArgstring(RexxMessage -> rm_Args[0]);
  193.  
  194.                 /* Free the message. */
  195.  
  196.             DeleteRexxMsg(RexxMessage);
  197.         }
  198.     }
  199. }
  200.  
  201.     /* ReplyRexxCommand(RexxMessage,Primary,Secondary,Result):
  202.      *
  203.      *    Sends a RexxMsg back to the rexx server, can include
  204.      *    result codes.
  205.      */
  206.  
  207. VOID __saveds __asm
  208. ReplyRexxCommand(register __a0 struct RexxMsg *RexxMessage,register __d0 LONG Primary,register __d1 LONG Secondary,register __a1 STRPTR Result)
  209. {
  210.         /* Valid pointer given? */
  211.  
  212.     if(RexxMessage)
  213.     {
  214.         if(RexxMessage -> rm_Node . mn_Node . ln_Type == NT_MESSAGE)
  215.         {
  216.                 /* No secondary result and results wanted? */
  217.  
  218.             if(Secondary == NULL && (RexxMessage -> rm_Action & RXFF_RESULT))
  219.             {
  220.                     /* Build result string... */
  221.  
  222.                 if(Result)
  223.                     Secondary = (LONG)CreateArgstring(Result,strlen(Result));
  224.             }
  225.  
  226.                 /* Set both results... */
  227.  
  228.             RexxMessage -> rm_Result1 = Primary;
  229.             RexxMessage -> rm_Result2 = Secondary;
  230.  
  231.                 /* ...and reply the message. */
  232.  
  233.             ReplyMsg(RexxMessage);
  234.         }
  235.     }
  236. }
  237.  
  238.     /* GetRexxCommand(RexxMessage):
  239.      *
  240.      *    Returns a pointer to the command string if
  241.      *    the RexxMsg is a command request.
  242.      */
  243.  
  244. STRPTR __saveds __asm
  245. GetRexxCommand(register __a0 struct RexxMsg *RexxMessage)
  246. {
  247.     if(RexxMessage)
  248.     {
  249.         if(RexxMessage -> rm_Node . mn_Node . ln_Type != NT_REPLYMSG)
  250.             return(RexxMessage -> rm_Args[0]);
  251.     }
  252.  
  253.     return(NULL);
  254. }
  255.  
  256.     /* GetRexxArg(RexxMessage):
  257.      *
  258.      *    Returns a pointer to the first RexxMsg argument.
  259.      */
  260.  
  261. STRPTR __saveds __asm
  262. GetRexxArg(register __a0 struct RexxMsg *RexxMessage)
  263. {
  264.     if(!RexxMessage)
  265.         return(NULL);
  266.     else
  267.         return(RexxMessage -> rm_Args[0]);
  268. }
  269.  
  270.     /* GetRexxResult1(RexxMessage):
  271.      *
  272.      *    Returns the 1st RexxMsg result.
  273.      */
  274.  
  275. LONG __saveds __asm
  276. GetRexxResult1(register __a0 struct RexxMsg *RexxMessage)
  277. {
  278.     if(!RexxMessage)
  279.         return(NULL);
  280.     else
  281.         return(RexxMessage -> rm_Result1);
  282. }
  283.  
  284.     /* GetRexxResult2(RexxMessage):
  285.      *
  286.      *    Returns the 2nd RexxMsg result.
  287.      */
  288.  
  289. LONG __saveds __asm
  290. GetRexxResult2(register __a0 struct RexxMsg *RexxMessage)
  291. {
  292.     if(!RexxMessage)
  293.         return(NULL);
  294.     else
  295.         return(RexxMessage -> rm_Result2);
  296. }
  297.  
  298.     /* IsSpace():
  299.      *
  300.      *    Returns TRUE if the input character is a space, tab,
  301.      *    carriage return, newline, form feed or vertical tab.
  302.      */
  303.  
  304. STATIC BYTE __regargs
  305. IsSpace(UBYTE c)
  306. {
  307.     if((c >= 13 && c <= 17) || c == 32)
  308.         return(TRUE);
  309.     else
  310.         return(FALSE);
  311. }
  312.  
  313.     /* GetToken(String,StartChar,AuxBuff,MaxLength):
  314.      *
  315.      *    Fills a string with the next given string
  316.      *    argument.
  317.      */
  318.  
  319. STRPTR __saveds __asm
  320. GetToken(register __a0 STRPTR String,register __a1 LONG *StartChar,register __a2 STRPTR AuxBuff,register __d0 LONG MaxLength)
  321. {
  322.     LONG i,StrEnd = 0,MaxPos = strlen(String);
  323.  
  324.         /* Last counter position. */
  325.  
  326.     if(MaxPos >= MaxLength + *StartChar)
  327.         MaxPos = MaxLength + *StartChar - 1;
  328.  
  329.         /* Already finished with argument string? */
  330.  
  331.     if(*StartChar <= strlen(String) - 1 && String && String[0] && AuxBuff && MaxLength)
  332.     {
  333.             /* Parse the argument string... */
  334.  
  335.         for(i = *StartChar ; i <= MaxPos ; i++)
  336.         {
  337.                 /* Skip leading blanks... */
  338.  
  339.             if(!StrEnd && IsSpace(String[i]))
  340.             {
  341.                 while(IsSpace(String[i]) && i < MaxPos)
  342.                 {
  343.                     i++;
  344.  
  345.                     (*StartChar)++;
  346.                 }
  347.             }
  348.  
  349.                 /* Found an argument. */
  350.  
  351.             if(IsSpace(String[i]) || String[i] == 0)
  352.             {
  353.                     /* Copy it to the auxiliary buffer. */
  354.  
  355.                 strncpy(AuxBuff,(String + *StartChar),StrEnd);
  356.                 AuxBuff[StrEnd] = 0;
  357.  
  358.                     /* Change the position counter (since
  359.                      * we can't use static data initialisation
  360.                      * calling program has to supply a
  361.                      * counter variable).
  362.                      */
  363.  
  364.                 (*StartChar) += StrEnd;
  365.  
  366.                 return(AuxBuff);
  367.             }
  368.  
  369.                 /* Increment character counter. */
  370.  
  371.             StrEnd++;
  372.         }
  373.     }
  374.  
  375.     return(NULL);
  376. }
  377.  
  378.     /* GetStringValue(String):
  379.      *
  380.      *    Returns the numeric value taken from given string
  381.      *    (just like atoi(), taken from example source code
  382.      *    by K&R).
  383.      */
  384.  
  385. LONG __saveds __asm
  386. GetStringValue(register __a0 STRPTR String)
  387. {
  388.     LONG    Value,i;
  389.     BYTE    Sign = 1;
  390.  
  391.         /* Valid argument given? */
  392.  
  393.     if(String)
  394.     {
  395.         if(String[0])
  396.         {
  397.                 /* Skip leading blank characters. */
  398.  
  399.             for(i = 0 ; String[i] == ' ' || String[i] == '\n' || String[i] == '\t' ; i++);
  400.  
  401.                 /* Remember sign extension. */
  402.  
  403.             if(String[i] == '+' || String[i] == '-')
  404.                 Sign = (String[i++] == '+') ? 1 : -1;
  405.  
  406.                 /* Convert from ASCII to decimal. */
  407.  
  408.             for(Value = 0 ; String[i] >= '0' && String[i] <= '9' ; i++)
  409.                 Value = 10 * Value + String[i] - '0';
  410.  
  411.                 /* Return real value. */
  412.  
  413.             return(Sign * Value);
  414.         }
  415.     }
  416.  
  417.     return(0);
  418. }
  419.  
  420.     /* BuildValueString(Value,String):
  421.      *
  422.      *    Puts a numeric value in decimal form into a
  423.      *    given string (similar to itoa(), taken from
  424.      *    example source code by K&R).
  425.      */
  426.  
  427. STRPTR __saveds __asm
  428. BuildValueString(register __d0 LONG Value,register __a0 STRPTR String)
  429. {
  430.     LONG    Sign,i = 0,j;
  431.     UBYTE    c;
  432.  
  433.         /* Valid argument given? */
  434.  
  435.     if(String)
  436.     {
  437.             /* Remember sign extension. */
  438.  
  439.         if((Sign = Value) < 0)
  440.             Value = -Value;
  441.  
  442.             /* Convert it into ASCII characters (in
  443.              * reverse order, i.e. 1234 = "4321").
  444.              */
  445.  
  446.         do
  447.             String[i++] = Value % 10 + '0';
  448.         while((Value /= 10) > 0);
  449.  
  450.             /* Add sign extension. */
  451.  
  452.         if(Sign < 0)
  453.             String[i++] = '-';
  454.  
  455.             /* String NULL-termination. */
  456.  
  457.         String[i] = 0;
  458.  
  459.             /* Reverse the string. */
  460.  
  461.         for(i = 0, j = strlen(String) - 1 ; i < j ; i++, j--)
  462.         {
  463.             c        = String[i];
  464.             String[i]    = String[j];
  465.             String[j]    = c;
  466.         }
  467.     }
  468.  
  469.     return(String);
  470. }
  471.  
  472.     /* AmigaToUpper(c):
  473.      *
  474.      *    Replacement for toupper() macro, also knows how to
  475.      *    map international characters to uppercase. Note: not
  476.      *    a real library module.
  477.      */
  478.  
  479. STATIC UBYTE __regargs
  480. AmigaToUpper(UBYTE c)
  481. {
  482.     /* -------- DEC ---------    -------- ASCII ------- */
  483.  
  484.     if((c >= 224 && c <= 254) || (c >= 'a' && c <= 'z'))
  485.         c -= 32;
  486.  
  487.     return(c);
  488. }
  489.  
  490.     /* RexxStrCmp(Source,Target):
  491.      *
  492.      *    Compares two strings ignoring case.
  493.      */
  494.  
  495. LONG __saveds __asm
  496. RexxStrCmp(register __a0 STRPTR Source,register __a1 STRPTR Target)
  497. {
  498.         /* Do the string comparison ignoring case. */
  499.  
  500.     for( ; AmigaToUpper(*Source) == AmigaToUpper(*Target) ; Source++, Target++)
  501.     {
  502.         if(!(*Source))
  503.             return(0);
  504.     }
  505.  
  506.     return(AmigaToUpper(*Source) - AmigaToUpper(*Target));
  507. }
  508.  
  509.     /* GetRexxMsg():
  510.      *
  511.      *    Picks up pending RexxMessages from a RexxHost and
  512.      *    returns them to the caller. I desired, will wait
  513.      *    for new messages to arrive if none is present yet.
  514.      */
  515.  
  516. struct RexxMsg * __saveds __asm
  517. GetRexxMsg(register __a0 struct RexxHost *RexxHost,register __d0 LONG Wait)
  518. {
  519.     struct RexxMsg *RexxMessage = NULL;
  520.  
  521.         /* Valid pointer given? */
  522.  
  523.     if(RexxHost)
  524.     {
  525.         if(RexxHost -> rh_SpecialID == 'REXX')
  526.         {
  527.                 /* Try to pick up a message. */
  528.  
  529.             while(!(RexxMessage = (struct RexxMsg *)GetMsg((struct MsgPort *)RexxHost)))
  530.             {
  531.                     /* No message available. Are we to wait? */
  532.  
  533.                 if(Wait)
  534.                     WaitPort((struct MsgPort *)RexxHost);
  535.                 else
  536.                     break;
  537.             }
  538.         }
  539.     }
  540.  
  541.         /* Return the result (may be NULL). */
  542.  
  543.     return(RexxMessage);
  544. }
  545.  
  546.     /* SendRexxMsg():
  547.      *
  548.      *    Sends a single (or a list of) command(s) to Rexx host
  549.      *    and returns the secondary result.
  550.      */
  551.  
  552. ULONG __saveds __asm
  553. SendRexxMsg(register __a0 STRPTR HostName,register __a1 STRPTR *MsgList,register __a2 STRPTR SingleMsg,register __d0 LONG GetResult)
  554. {
  555.     struct RexxMsg    *RexxMessage;
  556.     struct MsgPort    *HostPort,*ReplyPort;
  557.     ULONG         Result = 0;
  558.     SHORT         i;
  559.  
  560.         /* Valid pointers given? */
  561.  
  562.     if(HostName && (MsgList || SingleMsg))
  563.     {
  564.             /* Can we find the host? */
  565.  
  566.         if(HostPort = (struct MsgPort *)FindPort(HostName))
  567.         {
  568.                 /* Allocate a reply port. */
  569.  
  570.             if(ReplyPort = (struct MsgPort *)AllocMem(sizeof(struct MsgPort),MEMF_PUBLIC | MEMF_CLEAR))
  571.             {
  572.                 if((ReplyPort -> mp_SigBit = AllocSignal(-1)) != -1)
  573.                 {
  574.                     ReplyPort -> mp_Node . ln_Type    = NT_MSGPORT;
  575.                     ReplyPort -> mp_Flags        = PA_SIGNAL;
  576.                     ReplyPort -> mp_SigTask        = SysBase -> ThisTask;
  577.  
  578.                     NewList(&ReplyPort -> mp_MsgList);
  579.  
  580.                         /* Create a Rexx message. */
  581.  
  582.                     if(RexxMessage = (struct RexxMsg *)CreateRexxMsg(ReplyPort,"",HostName))
  583.                     {
  584.                             /* A list of arguments or only a single arg? */
  585.  
  586.                         if(MsgList)
  587.                         {
  588.                             for(i = 0 ; i < 16 ; i++)
  589.                                 RexxMessage -> rm_Args[i] = MsgList[i];
  590.                         }
  591.                         else
  592.                             RexxMessage -> rm_Args[0] = SingleMsg;
  593.  
  594.                             /* Do we want result codes? */
  595.  
  596.                         if(GetResult)
  597.                             RexxMessage -> rm_Action = RXFF_RESULT;
  598.  
  599.                             /* Send packet and wait for the reply. */
  600.  
  601.                         PutMsg(HostPort,RexxMessage);
  602.  
  603.                         WaitPort(ReplyPort);
  604.  
  605.                             /* Remember result. */
  606.  
  607.                         if(GetResult && !RexxMessage -> rm_Result1)
  608.                             Result = RexxMessage -> rm_Result2;
  609.  
  610.                             /* Remove Rexx message. */
  611.  
  612.                         DeleteRexxMsg(RexxMessage);
  613.                     }
  614.  
  615.                         /* Free reply port signal bit. */
  616.  
  617.                     FreeSignal(ReplyPort -> mp_SigBit);
  618.                 }
  619.  
  620.                     /* Free the replyport itself. */
  621.  
  622.                 FreeMem(ReplyPort,sizeof(struct MsgPort));
  623.             }
  624.         }
  625.     }
  626.  
  627.         /* Return the result. */
  628.  
  629.     return(Result);
  630. }
  631.  
  632.     /* GetRexxString():
  633.      *
  634.      *    Copy the result string returned by SendRexxMsg to user
  635.      *    buffer and/or remove the original string.
  636.      */
  637.  
  638. VOID __saveds __asm
  639. GetRexxString(register __d0 STRPTR SourceString,register __d1 STRPTR DestString)
  640. {
  641.         /* Valid pointer given? */
  642.  
  643.     if(SourceString)
  644.     {
  645.             /* Destination memory buffer given? */
  646.  
  647.         if(DestString)
  648.             strcpy(DestString,SourceString);
  649.  
  650.             /* Deallocate the original string. */
  651.  
  652.         DeleteArgstring(SourceString);
  653.     }
  654. }
  655.  
  656.     /* GetRexxClip():
  657.      *
  658.      *    Searches the rexx clip list for a node with given
  659.      *    name.
  660.      */
  661.  
  662. LONG __saveds __asm
  663. GetRexxClip(register __a0 UBYTE *Name,register __d0 LONG WhichArg)
  664. {
  665.         /* Do we have valid buffers and size? */
  666.  
  667.     if(Name)
  668.     {
  669.         if(Name[0])
  670.         {
  671.             struct RexxRsrc *Node;
  672.  
  673.                 /* Can we find the clip node? */
  674.  
  675.             if(Node = (struct RexxRsrc *)FindRsrcNode(&RexxSysBase -> rl_ClipList,Name,RRT_CLIP))
  676.             {
  677.                 if(WhichArg)
  678.                     return(Node -> rr_Arg1);
  679.                 else
  680.                     return(Node -> rr_Arg2);
  681.             }
  682.         }
  683.     }
  684.  
  685.     return(NULL);
  686. }
  687.